package com.choudou5.solr.web;

import com.choudou5.solr.framework.constants.DictConsts;
import com.choudou5.solr.framework.constants.ErrorResp;
import com.choudou5.solr.framework.holder.SysContextHolder;
import com.choudou5.solr.framework.util.PageJumpUtil;
import com.choudou5.solr.framework.util.RequestUtil;
import com.choudou5.solr.framework.util.SysSecurityUtil;
import com.choudou5.solr.job.JobService;
import com.choudou5.solr.service.ServiceHelper;
import com.choudou5.solr.service.sys.SysNoticeService;
import com.choudou5.solr.util.ConfigUtil;
import com.choudou5.solr.util.DateUtil;
import com.choudou5.solr.util.LogDeBugUtil;
import com.choudou5.solr.util.StrUtil;
import com.choudou5.solr.utils.SysDictUtil;
import com.choudou5.solr.utils.SysExceptionUtil;
import com.choudou5.solr.utils.oauth.OauthUtil;
import com.choudou5.solr.web.handler.BaseHandler;
import com.choudou5.solr.web.handler.SysHandlerHelper;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Name：管理控制台 Servlet
 * @@author choudou5
 * @@date 2018-07-14
 */
public class AdminConsoleServlet extends AbsBaseServlet {

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        LogDeBugUtil.debug("开始 初始化 上下文属性");
        //设置 全局属性
        SysContextHolder.initContext(getServletContext());
        getServletContext().setAttribute("oauthList", OauthUtil.getOauthList());
        getServletContext().setAttribute("sieName", ConfigUtil.getStr("sys.siteName"));
        getServletContext().setAttribute("__OPEN_DEBUG", ConfigUtil.getBool("sys.openDebug")); //开启调试
        getServletContext().setAttribute("sieName", ConfigUtil.getStr("sys.siteName"));
        SysContextHolder.setParam(SysNoticeService.HAS_SYS_NOTICE, ServiceHelper.singleton(SysNoticeService.class).getLast() != null);
        LogDeBugUtil.debug("完成 初始化 上下文属性");
        //注册Job
        JobService.regJob();
        //注册系统启动时间
        SysDictUtil.insertDictVal("系统首次启动", DictConsts.SYS_START_RUN_TIME, DateUtil.now());
    }

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        handler(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        handler(req, resp);
    }

    private void handler(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("utf-8");
        printlnJVMInfo(req); //打印jvm信息
        //检查安全访问（防止刷接口）
        if(!SysSecurityUtil.checkSafeAccess(req)){
            PageJumpUtil.errorOut(ErrorResp.Block_Access, req, resp);
            return;
        }
        //校验请求参数
        String url = RequestUtil.getReqUrl(req);
        String[] array = StrUtil.splitToArray(url, '/');
        if(array.length != 4) {
            logger.warn(url+" 请求地址格式有误，要求:/{api}/{module}/{method}");
            PageJumpUtil.errorOut(ErrorResp.Not_Found, req, resp);
            return;
        }
        String module = array[2], method = array[3];
        //校验 请求类型
        if(!BaseHandler.checkReqMapping(module, method, req.getMethod())) {
            PageJumpUtil.writeJson(ErrorResp.Not_Method_Allowed, resp);
            return;
        }
        //执行方法
        executeMethod(module, method, req, resp);
    }

    //执行方法
    private void executeMethod(String module, String method, HttpServletRequest req, HttpServletResponse resp){
        try {
            BaseHandler handler = SysHandlerHelper.getHandler(module);
            if(handler == null){
                PageJumpUtil.errorOut(ErrorResp.Not_Found, req, resp);
                return;
            }
            handler.execute(method, req, resp);
        } catch (Throwable e) {
            logger.error("AdminConsole", e);
            SysExceptionUtil.traceError(e, req);
            PageJumpUtil.errorOut(e, ErrorResp.Error, req, resp);
        }
    }

}
